package com.tianyu.inspection.service.websocket;

import com.tianyu.inspection.common.Constants;
import com.tianyu.inspection.common.protobuf.Telemetry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**********************************
 * @Author YSW
 * @Description
 * @Date 2020.12.18 - 11:04
 **********************************/

@Service
@Slf4j
public class TelemetryQueue {

    @Resource
    private WebSocketService webSocketService;

    /**
     * 实时遥测队列, 一个Tcp客户端对应一个遥测阻塞队列
     * Key 队列名称[项目ID-UavID/BoxID] 遥测分发队列
     * 遥测队列 BlockingQueue 生命周期
     *      1. 有遥测数据，任务开始，建立队列
     *      2. WebSocket遍历队列取遥测, 遍历WebSocket连接 对应项目连接发送遥测数据到客户端
     *      3. 任务结束移除遥测队列 或 关闭平台接数据功能，移除队列
     */
    public static Map<String, BlockingQueue<Telemetry.LiveData>> telemetryQueueMap = new ConcurrentHashMap<>(10);

    public void start() {
        log.info("开启线程[定时分发遥测到WebSocket客户端]...");
        Constants.SCHEDULED_EXECUTOR.scheduleAtFixedRate(this::sendWebSocket, 500, 1000, TimeUnit.MILLISECONDS);
    }

    public static void putTelemetry(String key, Telemetry.LiveData data) {
        BlockingQueue<Telemetry.LiveData> telemetryQueue;
        if (Objects.isNull(telemetryQueueMap.get(key))) {
            telemetryQueueMap.put(key, new LinkedBlockingQueue<>(10));
        }
        telemetryQueue = telemetryQueueMap.get(key);
        if (!telemetryQueue.offer(data)) {
            log.debug("队列" + key + "放入数据速度过快, 队列已满！");
        }
    }

    public void sendWebSocket() {
        telemetryQueueMap.forEach((tcpKey, telemetryQueue) -> {
            try {
                Telemetry.LiveData data = telemetryQueue.poll();
                if (Objects.nonNull(data)) {
                    log.debug("队列[{}] - {}任务[{}] 取出实时遥测数据 -> lng[ {} ], lat[ {} ], alt[ {} ]",
                            tcpKey, data.getSource(), data.getTaskId(), data.getLongitude(), data.getLatitude(), data.getAltitudeHeight());
                    webSocketService.sendTelemetryMessage(data);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}
